﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

namespace Karasoft.Extension
{
    public static class Extensions
    {
        public static Control FindControlR(this Control root, string id)
        {
            System.Web.UI.Control controlFound;
            if (root != null)
            {
                controlFound = root.FindControl(id);
                if (controlFound != null)
                {
                    return controlFound;
                }
                foreach (Control c in root.Controls)
                {
                    controlFound = c.FindControlR(id);
                    if (controlFound != null)
                    {
                        return controlFound;
                    }
                }
            }
            return null;
        }
        public static T FindControl<T>(this System.Web.UI.Control root, string controlId, bool recursive) where T : System.Web.UI.Control
        {

            if (root.Controls != null && root.Controls.Count > 0 && root.FindControl(controlId) != null)
            {

                return root.FindControl(controlId) as T;

            }

            else if (recursive)
            {

                return FindControl<T>(root, controlId, recursive);

            }

            return null;

        }
        public static T FindControlRecursive<T>(this Control parentControl, string id) where T : Control
        {
            T ctrl = default(T);

            if ((parentControl is T) && (parentControl.ID == id))
                return (T)parentControl;

            foreach (Control c in parentControl.Controls)
            {
                ctrl = FindControlRecursive<T>(c, id);

                if (ctrl != null)
                    break;
            }
            return ctrl;
        }
        //public static List<T> FindControlRecursive<T>(this Control parentControl, Type type) where T : Control
        //{
        //    T ctrl = default(T);
        //    var tlist = new List<T>();
        //    if ((parentControl is T) && (parentControl.GetType() == type))
        //    {
        //        ctrl = (T)parentControl;
        //        tlist.Add(ctrl);
        //        return tlist;
        //    }

        //    foreach (Control c in parentControl.Controls)
        //    {
        //        ctrl = FindControlRecursive<T>(c, id);

        //        if (ctrl != null)
        //            break;
        //    }
        //    return tlist;
        //}

        public static void FindControlsRecursive(this Control root, Type type, ref List<Control> list)
        {
            if (root.Controls.Count != 0)
            {
                foreach (Control c in root.Controls)
                {
                    if (c.GetType() == type)
                        list.Add(c);
                    else if (c.HasControls())
                        FindControlsRecursive(c, type, ref list);
                }
            }
        }

        public static bool HasArabicCharacters(this string text)
        {
            char[] glyphs = text.ToCharArray();
            foreach (char glyph in glyphs)
            {
                if (glyph >= 0x600 && glyph <= 0x6ff) return true;
                if (glyph >= 0x750 && glyph <= 0x77f) return true;
                if (glyph >= 0xfb50 && glyph <= 0xfc3f) return true;
                if (glyph >= 0xfe70 && glyph <= 0xfefc) return true;
            }
            return false;
        }

        public static bool IsNumeric(this string s)
        {
            foreach (char c in s)
            {
                if (!char.IsDigit(c) && c != '.')
                {
                    return false;
                }
            }

            return true;
        }



        public static bool IsNullOrEmpty(this String text)
        {
            return string.IsNullOrEmpty(text);
        }
        public static bool IsNotNullOrEmpty(this String text)
        {
            return !string.IsNullOrEmpty(text);
        }

        public static int? ToIntN(this String text)
        {
            int toreturn;
            if (string.IsNullOrEmpty(text))
                return null;
            else
            {
                if (int.TryParse(text, out toreturn))
                    return toreturn;
                else return null;
            }
        }

        public static int ToInt(this String text)
        {
           
            int toreturn;

            int.TryParse(text.ToEnInt(), out toreturn);
            
            return toreturn;
        }

        /// <summary>
        /// Convert arabic numbers to english number
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string ToEnInt(this string text)
        {
            text = text.IsNullOrEmpty() == true ? "0" : text;
            string toreurn = string.Empty;
            if (HasArabicCharacters(text))
            {
                foreach (char item in text)
                {
                    if (char.IsNumber(item))
                    {
                        switch (item)
                        {
                            case '١':
                                toreurn += "1";
                                break;
                            case '٢':
                                toreurn += "2";
                                break;
                            case '٣':
                                toreurn += "3";
                                break;
                            case '٤':
                                toreurn += "4";
                                break;
                            case '٥':
                                toreurn += "5";
                                break;
                            case '٦':
                                toreurn += "6";
                                break;
                            case '٧':
                                toreurn += "7";
                                break;
                            case '٨':
                                toreurn += "8";
                                break;
                            case '٩':
                                toreurn += "9";
                                break;
                            default:
                                toreurn += "0";
                                break;
                        }
                    }
                }
            }
            else
            {
                toreurn = text;
            }

            return toreurn;
        }

        public static long ToLong(this String text)
        {

            long toreturn;

            long.TryParse(text.ToEnInt(), out toreturn);

            return toreturn;
        }

        public static string ToArabicString(this int input)
        {
            return ToArabicString(input.ToString());
        }
        public static string ToArabicString(this string input)
        {
            string toreturn = string.Empty;

            System.Text.UTF8Encoding utf8Encoder = new UTF8Encoding();

            System.Text.Decoder utf8Decoder = utf8Encoder.GetDecoder();

            System.Text.StringBuilder convertedChars = new System.Text.StringBuilder();

            char[] convertedChar = new char[1];

            byte[] bytes = new byte[] { 217, 160 };

            char[] inputCharArray = input.ToCharArray();

            foreach (char c in inputCharArray)
            {

                if (char.IsDigit(c))
                {

                    bytes[1] = Convert.ToByte(160 + char.GetNumericValue(c));

                    utf8Decoder.GetChars(bytes, 0, 2, convertedChar, 0);

                    convertedChars.Append(convertedChar[0]);

                }

                else
                {

                    convertedChars.Append(c);

                }

            }

            toreturn = convertedChars.ToString();

            return toreturn;
        }

        public static bool? ToBooleanN(this String text)
        {
            bool toreturn;
            if (string.IsNullOrEmpty(text))
                return null;
            else
            {
                if (bool.TryParse(text, out toreturn))
                    return toreturn;
                else return null;
            }
        }

        public static bool ToBoolean(this String text)
        {
            bool toreturn;
            bool.TryParse(text, out toreturn);
            return toreturn;
        }

        public static void DataBind(this BaseDataBoundControl root, object DataSource)
        {
            root.DataSource = DataSource;
            root.DataBind();
        }

        public static string ToHijriDate(this DateTime odate, string format)
        {
            return Karasoft.Web.UI.Utility.DateUtility.ConvertToHijriDate(odate, format);
        }
        public static string ToHijriDate(this DateTime odate)
        {
            return Karasoft.Web.UI.Utility.DateUtility.ConvertToHijriDate(odate);
        }

        public static string ToHijriDate(this DateTime? odate, string format)
        {
            return Karasoft.Web.UI.Utility.DateUtility.ConvertToHijriDate(odate, format);
        }
        public static string ToHijriDate(this DateTime? odate)
        {
            if (odate.HasValue)
            {
                return Karasoft.Web.UI.Utility.DateUtility.ConvertToHijriDate(odate.Value,"yyyy/MM/dd");
            }
            else
            {
                return "";
            }
        }

        public static System.Drawing.Bitmap ResizeImage(this System.Drawing.Bitmap mg, Size newSize)
        {
            double ratio = 0d;
            double myThumbWidth = 0d;
            double myThumbHeight = 0d;
            int x = 0;
            int y = 0;

            System.Drawing.Bitmap bp;

            if ((mg.Width / Convert.ToDouble(newSize.Width)) > (mg.Height /
            Convert.ToDouble(newSize.Height)))
                ratio = Convert.ToDouble(mg.Width) / Convert.ToDouble(newSize.Width);
            else
                ratio = Convert.ToDouble(mg.Height) / Convert.ToDouble(newSize.Height);
            myThumbHeight = Math.Ceiling(mg.Height / ratio);
            myThumbWidth = Math.Ceiling(mg.Width / ratio);

            //Size thumbSize = new Size((int)myThumbWidth, (int)myThumbHeight);
            Size thumbSize = new Size((int)newSize.Width, (int)newSize.Height);
            bp = new System.Drawing.Bitmap(newSize.Width, newSize.Height);
            x = (newSize.Width - thumbSize.Width) / 2;
            y = (newSize.Height - thumbSize.Height);
            // Had to add System.Drawing class in front of Graphics ---
            System.Drawing.Graphics g = Graphics.FromImage(bp);
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            Rectangle rect = new Rectangle(x, y, thumbSize.Width, thumbSize.Height);
            g.DrawImage(mg, rect, 0, 0, mg.Width, mg.Height, GraphicsUnit.Pixel);

            return bp;
        }

        public static void CompressAndSaveImage(this System.Drawing.Image img, string fileName, int quality)
        {
            EncoderParameters parameters = new EncoderParameters(1);
            parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            img.Save(fileName, GetCodecInfo("image/jpeg"), parameters);
        }

        public static void CompressAndSaveImage(this System.Drawing.Image img, string fileName, int quality, ImageFormat format)
        {
            //ImageCodecInfo jgpEncoder = GetEncoder(format);
            EncoderParameters parameters = new EncoderParameters(1);
            parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            img.Save(fileName, GetEncoder(format), parameters);
        }

        private static ImageCodecInfo GetCodecInfo(string mimeType)
        {

            foreach (ImageCodecInfo encoder in ImageCodecInfo.GetImageEncoders())
                if (encoder.MimeType == mimeType)
                    return encoder;
            throw new ArgumentOutOfRangeException(
                string.Format("'{0}' not supported", mimeType));
        }

        private static ImageCodecInfo GetEncoder(ImageFormat format)
        {

            ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();

            foreach (ImageCodecInfo codec in codecs)
            {
                if (codec.FormatID == format.Guid)
                {
                    return codec;
                }
            }
            return null;
        }
    }
}

